package com.learn.aop.aspects;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

/**
 * 声明一个切面类测试环绕通知，通知功能模拟事务控制
 */
@Aspect
@Component
@Order(2)
public class TxAspect {


    // 使用@Around注解标明环绕通知方法
    @Around(value = "com.learn.aop.aspects.MyPointCut.transactionPointCut()")
    public Object manageTransaction(ProceedingJoinPoint proceedingJoinPoint) {
        // 通过在通知方法形参位置声明ProceedingJoinPoint类型的形参
        //Spring会将这个类型的对象传给我们
        Object targetMethodReturnValue = null;
        try {
            // 前置通知 setAutoCommit(false)
            System.out.println("[AOP 环绕通知] 前置通知 setAutoCommit(false)");
            Object[] args = proceedingJoinPoint.getArgs();
            targetMethodReturnValue = proceedingJoinPoint.proceed(args);
        } catch (Throwable e) {
            // 异常通知 rollback
            System.out.println("[AOP 环绕通知] 异常通知 rollback");

            throw new RuntimeException(e);
        }finally {
            // 后置通知 commit
            System.out.println("[AOP 环绕通知] 后置通知 commit");
        }
        // 返回通知
        System.out.println("[AOP 环绕通知] 返回通知");
        return targetMethodReturnValue;
    }
}
